<template>
  <div class="debounce-demo">
    <h2>按钮防抖示例</h2>
    
    <!-- 普通按钮 -->
    <div class="demo-section">
      <h3>1. 普通按钮（无防抖）</h3>
      <div class="demo-content">
        <button @click="normalClick">普通点击</button>
        <p>点击次数: {{ normalClickCount }}</p>
      </div>
    </div>

    <!-- 防抖按钮 -->
    <div class="demo-section">
      <h3>2. 防抖按钮（延迟1秒）</h3>
      <div class="demo-content">
        <button @click="debounceClick">防抖点击</button>
        <p>点击次数: {{ debounceClickCount }}</p>
      </div>
    </div>

    <!-- 立即执行的防抖按钮 -->
    <div class="demo-section">
      <h3>3. 立即执行的防抖按钮</h3>
      <div class="demo-content">
        <button @click="immediateDebounceClick">立即防抖点击</button>
        <p>点击次数: {{ immediateClickCount }}</p>
      </div>
    </div>

    <!-- 点击日志 -->
    <div class="demo-section">
      <h3>点击日志</h3>
      <div class="log-content">
        <ul>
          <li v-for="(log, index) in clickLogs" 
              :key="index"
              :class="log.type">
            {{ log.time }} - {{ log.message }}
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'DebounceDemo',
  
  data() {
    return {
      normalClickCount: 0,
      debounceClickCount: 0,
      immediateClickCount: 0,
      clickLogs: [],
      debounceTimer: null,
      immediateDebounceTimer: null
    };
  },

  methods: {
    // 普通点击
    normalClick() {
      this.normalClickCount++;
      this.addLog('normal', '普通点击被触发');
    },

    // 防抖点击
    debounceClick() {
      this.addLog('pending', '等待防抖...');
      clearTimeout(this.debounceTimer);
      this.debounceTimer = setTimeout(() => {
        this.debounceClickCount++;
        this.addLog('debounce', '防抖点击被触发');
      }, 1000);
    },

    // 立即执行的防抖点击
    immediateDebounceClick() {
      if (!this.immediateDebounceTimer) {
        this.immediateClickCount++;
        this.addLog('immediate', '立即防抖点击被触发');
      } else {
        this.addLog('pending', '防抖冷却中...');
      }

      clearTimeout(this.immediateDebounceTimer);
      this.immediateDebounceTimer = setTimeout(() => {
        this.immediateDebounceTimer = null;
      }, 1000);
    },

    // 添加日志
    addLog(type, message) {
      const time = new Date().toLocaleTimeString();
      this.clickLogs.unshift({ time, type, message });
      // 最多保留10条日志
      if (this.clickLogs.length > 10) {
        this.clickLogs.pop();
      }
    },

    // 创建防抖函数
    debounce(func, wait, immediate = false) {
      let timeout;
      return function(...args) {
        const context = this;
        const later = function() {
          timeout = null;
          if (!immediate) func.apply(context, args);
        };
        const callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(context, args);
      };
    }
  }
};
</script>

<style scoped>
.debounce-demo {
  max-width: 800px;
  margin: 0 auto;
  padding: 20px;
}

h2 {
  color: #2c3e50;
  border-bottom: 2px solid #1976d2;
  padding-bottom: 10px;
  margin-bottom: 30px;
}

.demo-section {
  background: #fff;
  border-radius: 8px;
  padding: 20px;
  margin-bottom: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

h3 {
  color: #1976d2;
  margin: 0 0 15px 0;
}

.demo-content {
  display: flex;
  align-items: center;
  gap: 20px;
}

button {
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  background-color: #1976d2;
  color: white;
  cursor: pointer;
  transition: background-color 0.3s;
}

button:hover {
  background-color: #1565c0;
}

.log-content {
  max-height: 200px;
  overflow-y: auto;
  background: #f8f9fa;
  border-radius: 4px;
  padding: 10px;
}

ul {
  list-style: none;
  padding: 0;
  margin: 0;
}

li {
  padding: 8px;
  margin: 4px 0;
  border-radius: 4px;
  font-family: monospace;
}

li.normal {
  background-color: #e3f2fd;
  color: #1976d2;
}

li.debounce {
  background-color: #e8f5e9;
  color: #2e7d32;
}

li.immediate {
  background-color: #fff3e0;
  color: #f57c00;
}

li.pending {
  background-color: #fafafa;
  color: #757575;
}

p {
  margin: 0;
  font-size: 16px;
  color: #666;
}
</style> 